package com.ruoyi.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectOne;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.TokenUtils;
import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.model.IdVo;
import com.ruoyi.system.api.model.LoginInfoVo;
import com.ruoyi.system.api.model.PageInfoVo;
import com.ruoyi.system.api.model.TbUserVo;
import com.ruoyi.user.domain.TbUser;
import com.ruoyi.user.service.TbUserService;
import com.ruoyi.user.mapper.TbUserMapper;
import com.ruoyi.user.utils.IdCardORCUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author 14475
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2023-01-12 19:35:09
*/
@Service
@Slf4j
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Resource
    TbUserMapper tbUserMapper;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Value("${site.token.timeOut}")
    private Integer timeOut;

    @Value("${site.token.password}")
    private String password;

    @Resource
    HttpServletRequest request;

    @Override
    public AjaxResult register(TbUserVo tbUserVo) {

        //1.判断手机号是否唯一
        TbUser one1 = this.getOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, tbUserVo.getUserMobile())
        );
        if(one1 != null) {

            return  AjaxResult.error("手机号已存在",null);
        }
        //2.判断验证码是否正确
        String code = (String) redisTemplate.opsForValue().get(tbUserVo.getUserMobile());
        if(!code.equals(tbUserVo.getCode())) {
            return AjaxResult.error(HttpStatus.ERROR,"验证码不正确,请重新输入！");
        }
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(tbUserVo,tbUser);
        String hashpw = BCrypt.hashpw(password, BCrypt.gensalt());
        tbUser.setUserPass(hashpw);
        tbUser.setUserName("小白"+tbUserVo.getUserMobile());
        //获取本地IP
        //String hostIp1 = IpUtils.getHostIp();
        //tbUser.setUserEmail(hostIp1);
        //获取客户端IP
        String hostIp = IpUtils.getIpAddr(request);
        tbUser.setUserEmail(hostIp);
        //存入数据库
        tbUserMapper.insert(tbUser);

        return AjaxResult.success();
    }

    @Override
    public AjaxResult login(LoginInfoVo loginInfoVo) {
        //1.判断  登录账号  或  手机号  是否唯一
        TbUser one = this.getOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, loginInfoVo.getUserName())
                .or().eq(TbUser::getUserMobile,loginInfoVo.getUserMobile())
        );
        if(one == null) {
            return AjaxResult.error(404,"用户/手机号不存在");
        }
        //2.判断密码是否正确
        if(!BCrypt.checkpw(loginInfoVo.getUserPass(),one.getUserPass())) {
            return AjaxResult.error(404,"密码错误,请重新输入！");
        }
        //获取token
        String token = TokenUtils.token()
                .setKey(password)
                .setClaim("userId", "" + one.getUserId())
                .setClaim("userName", one.getUserName())
                .makeToken();
        //存入redis 5分钟
        redisTemplate.opsForValue().set(token,token,timeOut, TimeUnit.MINUTES);
        TbUserVo tbUserVo = new TbUserVo();
        BeanUtils.copyProperties(one,tbUserVo);
        tbUserVo.setToken(token);
        tbUserVo.setUserPass(null);

        return AjaxResult.success(tbUserVo);
    }

    @Override
    public AjaxResult del(IdVo idVo) {
        //1.判断用户ID是否存在
        TbUser one = this.getOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserId, idVo.getId())
        );
        if(one == null) {
            return AjaxResult.error(404,"用户不存在");
        }
        tbUserMapper.deleteById(idVo.getId());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult set(TbUserVo tbUserVo) {
        //1.判断用户ID是否存在
        TbUser one = this.getOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserId, tbUserVo.getUserId())
        );
        if(one == null) {
            return AjaxResult.error(404,"用户不存在");
        }
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(tbUserVo,tbUser);
        String hashpw = BCrypt.hashpw(tbUserVo.getUserPass(), BCrypt.gensalt());
        tbUser.setUserPass(hashpw);
        tbUserMapper.updateById(tbUser);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult listByPage(PageInfoVo pageInfoVo) {
        //构建page
        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        //按照id倒序
        LambdaQueryWrapper<TbUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(TbUser::getUserId);

        Page<TbUser> tbUserPage = tbUserMapper.selectPage(page, wrapper);
        //通过stream流获取
        List<TbUserVo> records = tbUserPage.getRecords().stream().map(item -> {
            TbUserVo tbUserVo = new TbUserVo();
            BeanUtils.copyProperties(item, tbUserVo);
            return tbUserVo;
        }).collect(Collectors.toList());
        //返回数据
        Page<TbUserVo> tbUserVoPage = new Page<>();
        tbUserVoPage.setRecords(records);
        tbUserVoPage.setTotal(tbUserPage.getTotal());
        tbUserVoPage.setCurrent(tbUserPage.getCurrent());
        tbUserVoPage.setSize(tbUserPage.getSize());

        return AjaxResult.success(tbUserVoPage);
    }

    @Override
    public AjaxResult setCode(TbUserVo tbUserVo) {
        String res = IdCardORCUtils.IdCardORCUtils(tbUserVo.getImageUrl());
        JSONObject jsonObject = JSON.parseObject(res);
        //存入数据库
        TbUser tbUser = new TbUser();
        String name = (String) jsonObject.get("name");
        tbUser.setNickName(name);
        String num = (String) jsonObject.get("num");
        LambdaQueryWrapper<TbUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TbUser::getUserCard,tbUser.getUserCard());
        TbUser one = tbUserMapper.selectOne(wrapper);
        if(one != null) {
            return AjaxResult.success("身份证已经存在,请重新认证");
        }
        tbUser.setUserCard(num);
        String sex = (String) jsonObject.get("sex");
        if(sex.equals("男")) {
            tbUser.setUserSex(1);
        }else{
            tbUser.setUserSex(2);
        }
        String year = new SimpleDateFormat("yyyy").format(new Date());
        log.info("year:{}",year);
        Integer age = (Integer) jsonObject.get("birth".substring(1, 4));
        log.info("age:{}",age);
        tbUser.setUserAge(age);
        tbUser.setStatus(1);
        tbUserMapper.updateById(tbUser);

        return AjaxResult.success(tbUser);
    }


}




